home *** CD-ROM | disk | FTP | other *** search
/ Delphi Informant Complete 1995 - 2000 / Delphi Informant Complete 1995 to 2000.iso / Delphi Informant Magazine Complete Works SOURCE CODE 1998.rar / 1998 / May / di9805rs / Thread.pas < prev    next >
Pascal/Delphi Source File  |  1998-01-01  |  5KB  |  179 lines

  1. unit Thread;
  2.  
  3. interface
  4.  
  5. uses
  6.   Windows, Messages, SysUtils, Graphics, Controls,
  7.   Forms, Dialogs, Menus, StdCtrls, Classes, ExtCtrls;
  8.  
  9. type
  10.     // The linked list cells.
  11.     PEmpCell = ^TEmPEmpCell;
  12.     TEmPEmpCell = record
  13.         LastName  : String[20];
  14.         FirstName : String[20];
  15.         ID        : Longint;
  16.         NextName  : PEmpCell; // Next cell in name order.
  17.         NextID    : PEmpCell; // Next cell in ID order.
  18.     end;
  19.  
  20.   TThreadedListForm = class(TForm)
  21.     OrderOptions: TRadioGroup;
  22.     procedure FormCreate(Sender: TObject);
  23.     procedure Insert(last_name, first_name : String; emp_id : Longint);
  24.     procedure DrawList;
  25.     procedure FormPaint(Sender: TObject);
  26.     procedure FormDestroy(Sender: TObject);
  27.     procedure OrderOptionsClick(Sender: TObject);
  28.   private
  29.     { Private declarations }
  30.     top_sentinel    : TEmPEmpCell;
  31.     bottom_sentinel : TEmPEmpCell;
  32.   public
  33.     { Public declarations }
  34.   end;
  35.  
  36. var
  37.   ThreadedListForm: TThreadedListForm;
  38.  
  39. implementation
  40.  
  41. {$R *.DFM}
  42.  
  43. // Initialize the threaded list.
  44. procedure TThreadedListForm.FormCreate(Sender: TObject);
  45. begin
  46.     // Initialize the sentinels.
  47.     top_sentinel.NextName := @bottom_sentinel;
  48.     top_sentinel.NextID := @bottom_sentinel;
  49.     top_sentinel.LastName := '';
  50.     top_sentinel.FirstName := '';
  51.     top_sentinel.ID := -1;
  52.  
  53.     bottom_sentinel.NextName := nil;
  54.     bottom_sentinel.NextID := nil;
  55.     bottom_sentinel.LastName := #255;
  56.     bottom_sentinel.FirstName := #255;
  57.     bottom_sentinel.ID := 2147483647;
  58.  
  59.     // Create some data.
  60.     Insert('Anderson',  'John',   712);
  61.     Insert('Baker',     'Wendy',  132);
  62.     Insert('Cedras',    'Alice',  621);
  63.     Insert('Davis',     'Bill',   880);
  64.     Insert('Evans',     'Marvin', 204);
  65.     Insert('Fair',      'George', 492);
  66.     Insert('Gant',      'Cindy',  381);
  67.     Insert('Hennesey',  'Linda',  509);
  68.     Insert('Iverson',   'Sharon', 948);
  69. end;
  70.  
  71. // Add a new cell after the selected cell.
  72. procedure TThreadedListForm.Insert(last_name, first_name : String; emp_id : Longint);
  73. var
  74.     after_me, next_cell, new_cell : PEmpCell;
  75.     new_value, next_value         : String;
  76. begin
  77.     // Create the new cell.
  78.     New(new_cell);
  79.     new_cell^.LastName := last_name;
  80.     new_cell^.FirstName := first_name;
  81.     new_cell^.ID := emp_id;
  82.  
  83.     // Insert in the name thread.
  84.     new_value := last_name + ',' + first_name;
  85.     after_me := @top_sentinel;
  86.     repeat
  87.         next_cell := after_me^.NextName;
  88.         next_value := next_cell^.LastName + ',' +
  89.             next_cell^.FirstName;
  90.         if (next_value >= new_value) then break;
  91.         after_me := next_cell;
  92.     until (False);
  93.     new_cell^.NextName := next_cell;
  94.     after_me^.NextName := new_cell;
  95.  
  96.     // Insert in the ID thread.
  97.     after_me := @top_sentinel;
  98.     repeat
  99.         next_cell := after_me^.NextID;
  100.         if (next_cell^.ID >= emp_id) then break;
  101.         after_me := next_cell;
  102.     until (False);
  103.     new_cell^.NextID := next_cell;
  104.     after_me^.NextID := new_cell;
  105. end;
  106.  
  107. // Display the list, highlighting the selected item.
  108. procedure TThreadedListForm.DrawList;
  109. const
  110.     HGT = 17;
  111. var
  112.     cell_ptr : PEmpCell;
  113.     x, y     : Integer;
  114.     rect     : TRect;
  115. begin
  116.     // Clear the form.
  117.     rect.Left := 0;
  118.     rect.Top := 0;
  119.     rect.Right := ClientWidth;
  120.     rect.Bottom := ClientHeight;
  121.     Canvas.Brush.Color := clLtGray;
  122.     Canvas.FillRect(rect);
  123.  
  124.     // Display the list items.
  125.     x := OrderOptions.Left;
  126.     y := OrderOptions.Top + OrderOptions.Height + 5;
  127.  
  128.     if (OrderOptions.ItemIndex = 0) then
  129.         cell_ptr := top_sentinel.NextName // Order by name.
  130.     else
  131.         cell_ptr := top_sentinel.NextID;  // Order by ID.
  132.  
  133.     while (cell_ptr <> @bottom_sentinel) do
  134.     begin
  135.         // Display the text.
  136.         Canvas.TextOut(x, y,
  137.             Format('%-6d', [cell_ptr^.ID]) +
  138.             cell_ptr^.LastName + ', ' +
  139.             cell_ptr^.FirstName);
  140.         y := y + HGT;
  141.  
  142.         // Move to the next cell.
  143.         if (OrderOptions.ItemIndex = 0) then
  144.             cell_ptr := cell_ptr^.NextName // Order by name.
  145.         else
  146.             cell_ptr := cell_ptr^.NextID;  // Order by ID.
  147.     end;
  148. end;
  149.  
  150. // Redraw the list.
  151. procedure TThreadedListForm.FormPaint(Sender: TObject);
  152. begin
  153.     DrawList;
  154. end;
  155.  
  156. // Free all the linked list memory.
  157. // This doesn't matter for this example program. It would
  158. // be important if the program created and destroyed
  159. // many forms.
  160. procedure TThreadedListForm.FormDestroy(Sender: TObject);
  161. var
  162.     target : PEmpCell;
  163. begin
  164.     while (top_sentinel.NextName <> @bottom_sentinel) do
  165.     begin
  166.         target := top_sentinel.NextName;
  167.         top_sentinel.NextName := target^.NextName;
  168.         Dispose(target);
  169.     end;
  170. end;
  171.  
  172. // Redraw using the new ordering.
  173. procedure TThreadedListForm.OrderOptionsClick(Sender: TObject);
  174. begin
  175.     DrawList;
  176. end;
  177.  
  178. end.
  179.